package com.fingard.dsp.bank.directbank.zjtlcb02;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.ITransaction;
import com.fingard.dsp.bank.directbank.zjtlcb02.util.AESCipher;
import com.fingard.dsp.bank.directbank.zjtlcb02.util.MD5Util;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7515TodayTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7516HisTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.RetAtsTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.detail.RetAtsTransDetail;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;

/**
 * Created by F on 2018/9/13.
 */
public class ZJTLCB02Transaction extends ZJTLCB02Base implements ITransaction {
    /**
     * 历史明细查询
     * @param p_req7516
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsTrans d_7516_HisTrans(Req7516HisTrans p_req7516) throws Exception{
        RetAtsTrans retAtsTrans = new RetAtsTrans(p_req7516.reqHeader);
        retAtsTrans.writeStart();
        String tmpRespCode = "";
        String tmpRespInfo ="";
        try{
            //起始时间
            Calendar tmpCalendarFrom = Calendar.getInstance();
            tmpCalendarFrom.setTime(p_req7516.getDateFrom());
            //结束时间
            Calendar tmpCalendarTo = Calendar.getInstance();
            tmpCalendarTo.setTime(p_req7516.getDateTo());
            int tmpIntDateFrom = 0;
            int tmpIntDateTo = 0;
            while(tmpIntDateFrom<=tmpIntDateTo && StringHelper.isNullOrEmpty(tmpRespCode)) {
                Calendar tmpClndrStepTo = Calendar.getInstance();
                tmpClndrStepTo.setTime(tmpCalendarFrom.getTime());
                //当是跨月查询时，先查询起始日期到月末日期记录，再查询月末后一天日期到结束日期记录
                if (DateHelper.compareMonth(tmpCalendarFrom, tmpCalendarTo) == -1) {
                    tmpClndrStepTo.set(Calendar.DAY_OF_MONTH, tmpClndrStepTo.getActualMaximum(Calendar.DAY_OF_MONTH));
                } else {
                    tmpClndrStepTo.setTime(tmpCalendarTo.getTime());
                }
                int tmpNowReadStart = 1;//起始笔数
                int tmpNowReadNum = 0;//已查询笔数
                Map<String,Integer> tmpTotalNum = new HashMap<String, Integer>();
                while (tmpNowReadNum==0 || tmpNowReadNum<tmpTotalNum.get("totalCount")){
                    String seqNo=getQryTransID();
                    //报文头
                    JSONObject jsonHead = new JSONObject();
                    jsonHead.put("txSno",p_req7516.reqHeader.transSeqID);// 交易流水号
                    jsonHead.put("mrchSno",p_req7516.reqHeader.reqSeqID);// 商户业务编号
                    jsonHead.put("bussSeqNo",seqNo);// 银行业务编号
                    jsonHead.put("txTime", Format.DateTimeFormat.format(new Date()));// 交易时间
                    jsonHead.put("productId",""); // 产品ID
                    //报文体
                    JSONObject jsonBody = new JSONObject();
                    jsonBody.put("sourceType","J01");//	渠道类型
                    jsonBody.put("branchId",getBankConfig().getValueAsString("branchId"));//	发送方机构号
                    jsonBody.put("userId",getBankConfig().getValueAsString("userId"));//	服务请求者身份
                    jsonBody.put("orgSysId",getBankConfig().getValueAsString("orgSysId"));//	原始发起方系统ID
                    jsonBody.put("corpCode",getBankConfig().getValueAsString("corpCode"));//	法人类型代码
                    jsonBody.put("cardNo",p_req7516.actNum);//	账号
                    jsonBody.put("ccy",convertCurToBank(p_req7516.actCur));//币种
                    jsonBody.put("startDate",Format.Date8Format.format(tmpCalendarFrom.getTime()));//开始日期
                    jsonBody.put("endDate",Format.Date8Format.format(tmpClndrStepTo.getTime()));//终止日期
                    jsonBody.put("acctName","");//	账户名称
                    jsonBody.put("clientNo",bankFront.org);//	客户号
                    String data="<?xml version=\"1.0\" encoding=\"utf-8\"?><T><D><M><k>卡号</k><v>"+p_req7516.actNum+"</v></M></D><E><M><k>客户号</k><v>"+bankFront.org+"</v></M></E></T>";
                    jsonBody.put("signCert",ukeyData(data).trim());//	签名证书
                    jsonBody.put("totalNum",getBankConfig().getValueAsString("pageSize"));//本页记录总数 查询笔数，分页时使用
                    jsonBody.put("currentNum",tmpNowReadStart);//当前记录号 起始笔数，分页时使用
                    //报文内容
                    JSONObject jsonReqData = new JSONObject();
                    jsonReqData.put("head", jsonHead);
                    jsonReqData.put("body", jsonBody);
                    //拼接请求json串:data
                    JSONObject jsonObject = new JSONObject();
                    ZJTLCB02Header tlcb02Header = new ZJTLCB02Header();
                    tlcb02Header.seqNO = seqNo;
                    //验证开发者
                    String appAccessToken=checkDeveloper(seqNo);
                    tlcb02Header.appAccessToken = appAccessToken;
                    //MD5加密签名串
                    WriteBankLogLn("MD5加密原文:"+new StringBuilder(jsonReqData.toString()).append(seqNo).append(bankFront.keyID).toString());
                    String sign= MD5Util.md5_(new StringBuilder(jsonReqData.toString()).append(seqNo).append(bankFront.keyID).toString());
                    tlcb02Header.sign = sign;
                    JsonHeader(jsonObject, tlcb02Header);
                    jsonObject.put("reqData", jsonReqData);
                    WriteBankLogLn("发送银行请求报文原文："+jsonObject.toString());
                    //AES256加密
                    String aesData= AESCipher.encrypt(jsonReqData.toString(), MD5Util.md5_(seqNo + appAccessToken + bankFront.keyID));
                    jsonObject.put("reqData", aesData);
                    //发送请求报文
                    String[] bankResult = sendToBank(jsonObject.toString(),"dpstAcctTranQryBCDC");
                    //处理响应报文
                    if (bankResult[0].length() == 0) {
                        JSONObject jsonArray = JSONObject.fromObject(bankResult[1].replaceAll(" ",""));
                        //AES256解密
                        String rspData = AESCipher.decrypt(jsonArray.get("rspData").toString(), MD5Util.md5_(seqNo + appAccessToken + bankFront.keyID));
                        jsonArray.put("rspData",rspData);
                        WriteBankLogLn("银行返回已解密的报文："+jsonArray.toString());
                        if(!"".equals(jsonArray.get("errorCode")) && jsonArray.get("errorCode")!=null){
                            if(isActiveRetCode(jsonArray.get("errorCode").toString())){
                                JSONObject jsonRspData=JSONObject.fromObject(rspData);
                                JSONObject jsonBodys=(JSONObject)jsonRspData.get("body");
                                //开始处理报文体
                                if(!"".equals(jsonBodys) && jsonBodys!=null){
                                    if(jsonBodys.get("totalNum")==null || jsonBodys.get("totalRows")==null){
                                        tmpRespCode ="-1";
                                        tmpRespInfo = "返回字段totalNum或者totalRows缺失";
                                        break;
                                    }
                                    String recordCount = jsonBodys.get("totalNum").toString().trim();//获取页面记录条数
                                    String totalCount = jsonBodys.get("totalRows").toString().trim();//获取总记录数
                                    if(tmpTotalNum.containsKey("totalCount")){
                                        if(tmpTotalNum.get("totalCount").intValue()!=Integer.valueOf(totalCount).intValue()){
                                            tmpRespCode ="-1";
                                            tmpRespInfo = "相同条件前后查出来的总数不一致";
                                            break;
                                        }
                                    }else{
                                        if("0".equals(totalCount)){
                                            tmpRespCode ="0";
                                            tmpRespInfo = "该时间段的总明细条数为0";
                                            break;
                                        }
                                        tmpTotalNum.put("totalCount",Integer.valueOf(totalCount));//记录总条数
                                    }
                                    int readCount =0;
                                    String lbyAcctDtlArray=jsonBodys.get("lbyAcctDtlArray").toString();
                                    JSONArray json = JSONArray.fromObject(lbyAcctDtlArray);
                                    if(json.size()>0){
                                        for(int i=0;i<json.size();i++){
                                            JSONObject object = json.getJSONObject(i);
                                            RetAtsTransDetail detail = new RetAtsTransDetail();
                                            detail.actArea=p_req7516.actArea;//账户区域
                                            detail.actNum=p_req7516.actNum;//银行账号
                                            detail.recAccNum=object.get("acctNo")!=null?object.get("acctNo").toString():"";//收方银行账号
                                            detail.recAccName=object.get("acctName")!=null?object.get("acctName").toString():"";//收方账户名称
                                            detail.recAccBank=object.get("openBankName")!=null?object.get("openBankName").toString():"";//收方银行
                                            if(object.get("oriTranDate")==null){
                                                tmpRespCode = "-1";
                                                tmpRespInfo = "交易日期字段未返回";
                                                break;
                                            }
                                            detail.tranDate=DateHelper.convertD8toD10(object.get("oriTranDate").toString());//交易日期
                                            String tranTime=object.get("oriTxnTime")!=null?object.get("oriTxnTime").toString():"00:00:00";//交易时间
                                            detail.tranTime=detail.tranDate+" "+DateHelper.getFormat8Time(tranTime);//交易时间
                                            detail.valueDate=detail.tranDate;//起息日，银行没有返回就用tranDate交易日期
                                            String drAmt=object.get("drAmt")!=null?object.get("drAmt").toString().trim():"";//借方金额
                                            String crAmt=object.get("crAmt")!=null?object.get("crAmt").toString().trim():"";//贷方金额
                                            if(!"0.0".equals(drAmt)){
                                                if(drAmt.indexOf("-")>=0){
                                                    detail.cdFlag="2";
                                                    detail.tranAmt=drAmt.substring(1);//交易金额
                                                }
                                                detail.cdFlag="1";
                                                detail.tranAmt=drAmt;//交易金额
                                            }else if(!"0.0".equals(crAmt)){
                                                if(crAmt.indexOf("-")>=0){
                                                    detail.cdFlag="1";
                                                    detail.tranAmt=crAmt.substring(1);//交易金额
                                                }
                                                detail.cdFlag="2";
                                                detail.tranAmt=crAmt;//交易金额
                                            }else {
                                                tmpRespCode = "-1";
                                                tmpRespInfo = "借方/贷方金额都为0.0，或者存在空值，明细异常";
                                                break;
                                            }
                                            detail.accBal=object.get("olAcctBal")!=null?object.get("olAcctBal").toString():"";//账户余额
                                            detail.postTimestamp="";//时间戳，银行没有就空
                                            detail.billType="";//单据或票据类型，银行没有就空
                                            detail.billNum="";//单据或票据号码，银行没有就空
                                            String note = object.get("remark")!=null?object.get("remark").toString():"";
                                            detail.usage=note;//摘要
                                            detail.abstr=pickupAbstr(note);//对账码
                                            detail.payCode="";//支付码
                                            detail.comment="";//备注
                                            detail.askNumber=object.get("oriTranSeqNo")!=null?object.get("oriTranSeqNo").toString():"";//支付流水号
                                            detail.reqBatchNO="";//支付批号
                                            detail.cur=object.get("ccy")!=null?convertCurToATS(object.get("ccy").toString())
                                                    :convertCurToATS(getBankConfig().getMapKeyByValue("curActMapping", p_req7516.actNum));//币种
                                            detail.seqId="";//序列号
                                            detail.isCollection="";//是否现金池，银行没有就空
                                            detail.originator="";//柜员号
                                            detail.busType="";//新业务类型
                                            detail.urid=object.get("oriTranSeqNo")!=null?object.get("oriTranSeqNo").toString():"";//唯一明细号
                                            retAtsTrans.writeRetDetail(detail);
                                            readCount++;
                                        }
                                        //查询记录数和遍历数不一致
                                        if(readCount!=Integer.valueOf(recordCount)){
                                            tmpRespCode = "-1";
                                            tmpRespInfo = "统计明细有误";
                                            break;
                                        }
                                        tmpNowReadStart +=readCount;
                                        tmpNowReadNum +=readCount;
                                    }else {
                                        tmpRespCode ="-1";
                                        tmpRespInfo = "统计明细有误";
                                        break;
                                    }
                                }else {
                                    tmpRespCode ="0";
                                    tmpRespInfo = "该时间段的总明细条数为0";
                                    break;
                                }
                            }else {
                                tmpRespCode = "-1";
                                tmpRespInfo = jsonArray.get("errorMsg").toString();
                                break;
                            }
                        }else {
                            tmpRespCode = "-1";
                            tmpRespInfo = "响应码未返回";
                            break;
                        }
                    }else {
                        tmpRespCode = "-1";
                        tmpRespInfo = bankResult[1];
                        break;
                    }
                }
                tmpCalendarFrom = tmpClndrStepTo;
                tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
                tmpIntDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                tmpIntDateTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
            }
        }catch (Exception ex){
            tmpRespCode = "-1";
            tmpRespInfo = ex.getMessage();
            ex.printStackTrace();
            WriteBankLogLn("查询明细异常:"+ex);
        }
        if ("-1".equals(tmpRespCode)) {
            retAtsTrans = new RetAtsTrans(p_req7516.reqHeader);
            retAtsTrans.writeStart();//写返回ATS的统一头部信息
            retAtsTrans.writeRespCode(tmpRespCode);
            retAtsTrans.writeRespInfo(tmpRespInfo);
        }else if(retAtsTrans.getWrittenRdCount() == 0) {
            retAtsTrans.writeRespInfo("交易为空");
            retAtsTrans.writeRespCode("0");
        }
        retAtsTrans.writeEnd();
        return retAtsTrans;
    }

    /**
     * 今日明细查询
     * @param p_req7515
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsTrans d_7515_TodayTrans(Req7515TodayTrans p_req7515) throws Exception{
        Req7516HisTrans p_req7516 = new Req7516HisTrans(p_req7515.reqHeader);
        p_req7516.actArea = p_req7515.actArea;
        p_req7516.actCur = p_req7515.actCur;
        p_req7516.actNum = p_req7515.actNum;
        String date = Format.Date8Format.format(new Date());
        p_req7516.dateFrom = date;
        p_req7516.dateTo = date;
        return d_7516_HisTrans(p_req7516);
    }
}
